﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Data;
using System.Net.Http;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Win32;
using System.IO;
using System.Runtime.InteropServices;

namespace BGBingTool
{
    public partial class MainForm : Form
    {
        private string ToolRegKey = "Software\\BGBingTool";
        private string ToolStartKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Run\\BGBingTool";

        private IDesktopWallpaper Wallpaper;

        public class BG360Categary
        {
            public String Id { get; set; }
            public String Name { get; set; }
            public String Count { get; set; }
            override public String ToString() { return Name + " - " + Count; }
        }


        [DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
        public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);

        public MainForm()
        {
            InitializeComponent();
            this.Wallpaper = (IDesktopWallpaper)new DesktopWallpaper();

            ReloadConf();
        }
        public void ReloadConf()
        {
            try
            {
                RegistryKey key = Registry.CurrentUser.CreateSubKey(ToolRegKey);
                edit_save_dir.Text = key.GetValue("SaveDir", "./Data").ToString();
                cbox_multi_screen.Checked = (int)key.GetValue("MultiScreen", 0) > 0 ? true : false;
            }
            catch
            {
            }

        }
        public void ApplyAllInfo()
        {
            try
            {
                RegistryKey key = Registry.CurrentUser.CreateSubKey(ToolRegKey, true);
                key.SetValue("SaveDir", edit_save_dir.Text);
                key.SetValue("MultiScreen", cbox_multi_screen.Checked ? 1 : 0);
                key.SetValue("Offset", int.Parse(edit_num_offset.Text));
                key.Close();
            }
            catch
            {
            }
        }

        public void AutoStart(bool bEnable)
        {
            try
            {
                if (bEnable)
                {
                    Registry.CurrentUser.SetValue(ToolStartKey, Application.ExecutablePath);
                }
                else
                {
                    Registry.CurrentUser.DeleteValue(ToolStartKey, false);
                }
            }
            catch
            {

            }
        }

        public async Task<string> HttpGetBing(int offset = 0, int count = 1)
        {
            string baseUrl = $"https://www.bing.com/HPImageArchive.aspx?format=js&idx={offset}&n={count}";
            HttpClient c = new HttpClient();
            c.Timeout = new TimeSpan(0, 0, 30);
            var resp = await c.GetAsync(baseUrl);
            return await resp.Content.ReadAsStringAsync();
        }

        public async Task<string> HttpGet360_Sync()
        {
            string baseUrl = "http://wallpaper.apc.360.cn/index.php?c=WallPaperAndroid&a=getAllCategories";
            HttpClient c = new HttpClient();
            c.Timeout = new TimeSpan(0, 0, 30);
            var resp = await c.GetAsync(baseUrl);
            return await resp.Content.ReadAsStringAsync();
        }

        public async Task<string> HttpGet360(int cid = 1, int offset = 0, int count = 10)
        {
            string baseUrl = $"http://wallpaper.apc.360.cn/index.php?c=WallPaperAndroid&a=getAppsByCategory&cid={cid}&start={offset}&count={count}";
            HttpClient c = new HttpClient();
            c.Timeout = new TimeSpan(0, 0, 30);
            var resp = await c.GetAsync(baseUrl);
            return await resp.Content.ReadAsStringAsync();
        }

        public async Task HttpDownload(string url, string path)
        {
            HttpClient c = new HttpClient();
            var resp = await c.GetAsync(url);
            var stream = await resp.Content.ReadAsStreamAsync();
            var fs = new FileStream(path, FileMode.OpenOrCreate);
            var buff = new byte[1024 * 10];
            var size = stream.Read(buff, 0, 1024 * 10);
            while (size > 0)
            {
                fs.Write(buff, 0, size);
                size = stream.Read(buff, 0, 1024 * 10);
            }
            fs.Close();
            stream.Close();
        }

        private void btn_clear_Click(object sender, EventArgs e)
        {
            Registry.CurrentUser.DeleteSubKeyTree(ToolRegKey, false);
            AutoStart(false);
        }

        private void btn_apply_Click(object sender, EventArgs e)
        {
            // 获取更新日期最新的文件
            var imgList = new List<String>();
            DirectoryInfo d = new DirectoryInfo(edit_save_dir.Text);
            var imgs = d.GetFiles("*.jpg");
            imgs = imgs.OrderBy(g => g.CreationTime).Reverse().ToArray();
            foreach (var f in imgs)
            {
                imgList.Add(f.FullName);
            }
            // Debug.WriteLine(imgList);
            // 设置壁纸
            if (cbox_multi_screen.Checked)
            {
                SetBGForScreens(imgList);
            }
            else
            {
                // SystemParametersInfo(20, 0, imgList.First(), 2);
                Wallpaper.SetWallpaper(null, imgList.First());
                Debug.WriteLine($"Set Bg for all screen {imgList.First()}");
            }
        }

        private void btn_select_dir_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            dlg.Description = "选择一个空的文件夹:";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                edit_save_dir.Text = dlg.SelectedPath;
            }
        }

        public void SetBGForScreen(int id, string path)
        {
            uint monitorCount = Wallpaper.GetMonitorDevicePathCount();
            var screenIds = new List<string>();
            for (uint i = 0; i < monitorCount; i++)
            {
                if (id < 0 || id == i)
                {
                    screenIds.Add(Wallpaper.GetMonitorDevicePathAt(i));
                }
            }
            foreach (string sid in screenIds)
            {
                Debug.WriteLine($"{sid}");
                Wallpaper.SetWallpaper(sid, path);
            }
        }

        public void SetBGForScreens(List<string> paths)
        {
            uint monitorCount = Wallpaper.GetMonitorDevicePathCount();
            int uLastIndex = 0;
            for (uint i = 0; i < monitorCount; i++)
            {
                if (i < paths.Count)
                {
                    uLastIndex = (int)i;
                }
                var screen_id = Wallpaper.GetMonitorDevicePathAt(i);
                if (screen_id != null && screen_id.Length > 2)
                    Wallpaper.SetWallpaper(screen_id, paths[uLastIndex]);
                Debug.WriteLine($"Set Bg for {i} {screen_id} using {paths[uLastIndex]}");
            }
        }

        private void btn_save_conf_Click(object sender, EventArgs e)
        {
            ApplyAllInfo();
        }

        private async void btn_bing_down_Click(object sender, EventArgs e)
        {
            Directory.CreateDirectory(edit_save_dir.Text);

            int nScreenCount = (int)Wallpaper.GetMonitorDevicePathCount();
            int nWant = (int)edit_num_count.Value;
            nWant = nWant > 0 ? nWant : nScreenCount;

            label_status.Text = "抓取列表...";
            try
            {
                var jsonResp = await HttpGetBing((int)edit_num_offset.Value, nWant);
                JsonDocument doc = JsonDocument.Parse(jsonResp);
                var imgs = doc.RootElement.GetProperty("images");
                // 下载
                int nIndex = 0;
                foreach (var ele in imgs.EnumerateArray())
                {
                    string imgUrl = $"https://www.bing.com/{ele.GetProperty("url").GetString()}";
                    string path = $"{edit_save_dir.Text}/Bing_{ele.GetProperty("fullstartdate").GetString()}.jpg";
                    var path2 = Path.GetFullPath(path);
                    await HttpDownload(imgUrl, path2);
                    nIndex += 1;
                    label_status.Text = $"正在下载 Bing 壁纸 {nIndex}/{imgs.GetArrayLength()} => {path}...";
                }
            }
            catch (Exception ex)
            {
                label_status.Text = "抓取图片超时!";
                return;
            }
        }

        private async void btn_360_sync_Click(object sender, EventArgs e)
        {
            label_status.Text = "抓取分类...";
            try
            {
                var jsonResp = await HttpGet360_Sync();
                JsonDocument doc = JsonDocument.Parse(jsonResp);
                var imgs = doc.RootElement.GetProperty("data");
                // Debug.WriteLine(imgs);
                comboBox_360_sync.Items.Clear();
                foreach (var img in imgs.EnumerateArray())
                {
                    var tmp = new BG360Categary
                    {
                        Name = img.GetProperty("name").GetString(),
                        Id = img.GetProperty("id").GetString(),
                        Count = img.GetProperty("totalcnt").GetString()
                    };
                    comboBox_360_sync.Items.Add(tmp);
                }
            }
            catch (Exception ex)
            {
                label_status.Text = "抓取列表失败";
                return;
            }
            comboBox_360_sync.SelectedIndex = 0;
        }

        private void comboBox_360_sync_SelectedIndexChanged(object sender, EventArgs e)
        {
            var item = (BG360Categary)comboBox_360_sync.SelectedItem;
            label_categery.Text = $"ID: {item.Id}\r\n类别： {item.Name}\r\n图片数量: {item.Count}";
        }

        private async void btn_360_down_Click(object sender, EventArgs e)
        {
            var cur_item = (BG360Categary)comboBox_360_sync.SelectedItem;
            if (cur_item == null)
            {
                MessageBox.Show("请先更新图片分类!", "操作错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            Directory.CreateDirectory(edit_save_dir.Text);

            int nScreenCount = (int)Wallpaper.GetMonitorDevicePathCount();
            int nWant = int.Parse(edit_360_count.Text);
            nWant = nWant > 0 ? nWant : nScreenCount;

            label_status.Text = "抓取列表...";
            try
            {
                var jsonResp = await HttpGet360(int.Parse(cur_item.Id), int.Parse(edit_360_start.Text), nWant);
                JsonDocument doc = JsonDocument.Parse(jsonResp);
                var imgs = doc.RootElement.GetProperty("data");
                // 下载
                label_status.Text = "开始下载...";
                int nIndex = 0;
                foreach (var ele in imgs.EnumerateArray())
                {
                    string imgUrl = ele.GetProperty("url").GetString();
                    JsonElement ele_val;
                    String pid = "";
                    if (ele.TryGetProperty("pid", out ele_val))
                    {
                        pid = ele_val.GetString();
                    }
                    else
                    {
                        pid = ele.GetProperty("id").GetString();
                    }
                    string path = $"{edit_save_dir.Text}/360_{pid}.jpg";
                    var path2 = Path.GetFullPath(path);
                    await HttpDownload(imgUrl, path2);
                    nIndex += 1;
                    label_status.Text = $"正在下载 360 壁纸 {nIndex}/{imgs.GetArrayLength()} => {path}...";
                }
            }
            catch (Exception ex)
            {
                label_status.Text = "抓取图片超时!";
                return;
            }
        }
    }
}
